﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace ClipboardManager
{
    public class ClipboardItem
    {
        private IDataObject ClipboardData;

        public string DataString { get; set; }
        public Bitmap DataBitmap { get; set; }

        public string Rtf { get; set; }

        internal enum Type
        {
            Text,
            Html,
            Rtf,
            Bitmap,
            Files
        }
        internal Type ClipboardType { get; set; }

        internal InfoStruct info = new InfoStruct();

        internal struct InfoStruct
        {
            public DateTime Time { get; set; }
            public string WindowText { get; set; }
            public string Format { get; set; }
            public string[] Formats { get; set; }
            public string Length { get; set; }
        }


        private string[] KnownTypes = new string[] { "text/html", "Rich Text Format", "UnicodeText", "Bitmap", "application/x-moz-nativeimage", "FileDrop" };

        public ClipboardItem()
        {
            ClipboardData = Clipboard.GetDataObject();

            DoWork();

            if (ClipboardType == Type.Bitmap)
                info.Length = DataBitmap.Size.ToString();
            else
                info.Length = DataString.Length.ToString();
            
        }


        private void DoWork()
        {
            DataString = "";
            string[] formats = ClipboardData.GetFormats(true);
            string format = FindFormat(formats);

            info.Format = format;
            info.Formats = formats;
            info.Time = DateTime.Now;
            info.WindowText = GetActiveWindowText;

            switch (format)
            {
                case "":
                    if (formats.Length == 0)
                    {
                        info.Formats = new string[1] { "Empty" };
                        info.Format = "Empty";
                        DataString = "Empty";
                    }
                    else
                        format = "Unknown";
                    ClipboardType = Type.Text;
                    break;

                case "Bitmap":
                    ClipboardType = Type.Bitmap;
                    DataBitmap = (Bitmap)ClipboardData.GetData(DataFormats.Bitmap, true);
                    break;

                case "application/x-moz-nativeimage":
                    ClipboardType = Type.Bitmap;
                    DataBitmap = (Bitmap)ClipboardData.GetData(DataFormats.Bitmap, true);
                    break;


                case "UnicodeText":
                    ClipboardType = Type.Text;
                    DataString = (string)ClipboardData.GetData(DataFormats.UnicodeText, true);
                    break;

                case "Rich Text Format":
                    ClipboardType = Type.Rtf;
                    DataString = (string)ClipboardData.GetData(DataFormats.Rtf, true);
                    break;

                case "FileDrop":
                    ClipboardType = Type.Files;
                    DataString = Helper.ArrToList((string[])ClipboardData.GetData(DataFormats.FileDrop, true));
                    break;

                case "text/html":
                    ClipboardType = Type.Html;
                    DataString = (string)ClipboardData.GetData(DataFormats.Html, true);
                    break;

                default:
                    ClipboardType = Type.Text;
                    DataString = ClipboardData.GetData(formats[0]).ToString();
                    break;
            }

        }


        private string FindFormat(string[] formats)
        {
            foreach (string k in KnownTypes)
            {
                foreach (string f in formats)
                {
                    if (k == f) return k;
                }
            }
            return "";
        }

        public static string GetActiveWindowText
        {
            get
            {
                const int nChars = 256;
                int handle = 0;
                StringBuilder Buff = new StringBuilder(nChars);

                handle = NativeMethods.GetForegroundWindow();

                NativeMethods.GetWindowText(handle, Buff, nChars);

                return Buff.ToString();
            }
        }


        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("Format: " + info.Format);
            sb.Append("Able formats: " + info.Formats[0]);

            for (int i = 1; i < info.Formats.Length - 1; i++)
            {
                sb.Append(',' + info.Formats[i]);
            }

            sb.AppendLine();

            sb.AppendLine("Window Text: " + info.WindowText);

            sb.AppendLine("Time: " + info.Time.ToLongTimeString());

            sb.Append("Text: " + DataString);

            return sb.ToString();
        }

        public void SetItemToClipboard()
        {
            if (ClipboardType == ClipboardItem.Type.Text ||
                ClipboardType == ClipboardItem.Type.Html ||
                ClipboardType == ClipboardItem.Type.Files ||
                ClipboardType == ClipboardItem.Type.Rtf)
                Clipboard.SetText(DataString);

            else if (ClipboardType == ClipboardItem.Type.Bitmap)
                Clipboard.SetImage(DataBitmap);
        }

    }
}
